// ==UserScript== // @name Bilibili 批量删除关注 // @description 在“Bilibili-我的关注”页面中批量选择时,可以进行批量取消关注。 // @version 1.4 // @author Myitian&Mscststs // @license MIT // @namespace myitian.bili.followUsers-batchDelete // @match https://space.bilibili.com/* // @require https://greasyfork.org/scripts/38220-mscststs-tools/code/MSCSTSTS-TOOLS.js?version=713767 // @grant none // ==/UserScript== if (/https:\/\/space\.bilibili\.com\/\d+\/fans/.test(window.location)) { window.addEventListener('click', addBtnFunc, true); window.addEventListener('click', checkboxFunc, true); initMessageBox(); } var checkedList = []; var grayIcon = 'background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWAQMAAAD+ev54AAAABlBMVEUAAADL0NgxrV+XAAAAAXRSTlMAQObYZgAAACNJREFUCNdjAIMKBK7//wOMDaDQyJMwhkH7/x8Y5P8/AJkIAPm2EgQtoFFGAAAAAElFTkSuQmCC);'; var blueIcon = 'background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWAQMAAAD+ev54AAAABlBMVEUAAAAAo9sxTF25AAAAAXRSTlMAQObYZgAAACNJREFUCNdjAIMKBK7//wOMDaDQyJMwhkH7/x8Y5P8/AJkIAPm2EgQtoFFGAAAAAElFTkSuQmCC);'; var digitRegex = /\d+/; //更新图标 function updateIcon() { var i = document.getElementById('my-fubd--delbtn-icon'); if (i) { if (checkedList.length == 0) { i.style = grayIcon; } else { i.style = blueIcon; } } } //获取Cookie function getCookie(cname) { var name = cname + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i].trim(); if (c.indexOf(name) == 0) return c.substring(name.length, c.length); } return ""; } //取消关注POST请求 async function xhrPost(fid, csrf) { var xhr = new XMLHttpRequest(); xhr.open('POST', 'https://api.bilibili.com/x/relation/modify'); xhr.withCredentials = true; xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('fid=' + fid + '&act=2&csrf=' + csrf); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } }; } //添加按钮功能 function addBtnFunc() { var btnEle = document.getElementsByClassName('icon-multiple')[0]; if (btnEle && event.target == btnEle && btnEle.getAttribute('my-fubd--func-already-added') != 'true') { btnEle.setAttribute('my-fubd--func-already-added', 'true'); btnEle.addEventListener('click', batchDeleteBtnFunc); } } //添加取消关注按钮 function batchDeleteBtnFunc() { var root = document.getElementsByClassName('follow-action-fixtop clearfix')[0]; var back = document.getElementsByClassName('back-to-info icon')[0]; back.addEventListener('click', cancelBtnFunc); var cancel = root.querySelector('.select-cancel'); cancel.addEventListener('click', cancelBtnFunc); var btns = root.firstElementChild; var li = document.createElement('li'); var i = document.createElement('i'); i.className = 'icon'; i.id = 'my-fubd--delbtn-icon'; i.style = grayIcon; li.addEventListener('click', loadMessageBox); li.appendChild(i); li.innerHTML += '取消关注'; btns.appendChild(li); } //复选框功能 function checkboxFunc() { var target = event.target; if (target.className == 'follow-select') { target = target.firstElementChild; } var link, index; if (target.className == 'icon icon-follow-watched icon-follow-selected') { //uncheck link = target.parentNode.parentNode.querySelector('.title'); index = checkedList.indexOf(digitRegex.exec(link.href)[0]); if (index != -1) { checkedList.splice(index, 1); updateIcon(); } } else if (target.className == 'icon icon-follow-watched') { //check link = target.parentNode.parentNode.querySelector('.title'); var href = digitRegex.exec(link.href)[0]; index = checkedList.indexOf(href); if (index == -1) { checkedList.push(href); updateIcon(); } } } //取消选择按钮功能 function cancelBtnFunc() { checkedList = []; updateIcon(); } //初始化消息框 function initMessageBox() { if (document.getElementById('my-fubd--container')) return; var base = document.createElement('div'); base.className = 'modal-container edit-video-modal'; base.id = 'my-fubd--container'; base.style = 'display: none;'; base.innerHTML = ''; /* 未压缩内容如下: */ document.body.appendChild(base); document.getElementById('my-fubd--msgbox-close').addEventListener('click', exitMessageBox); document.getElementById('my-fubd--msgbox-a').addEventListener('click', mainFunc); } //加载消息框 function loadMessageBox() { var len = checkedList.length; if (len == 0) return; document.getElementById('my-fubd--msgbox-title').innerText = '你正在删除' + checkedList.length + '个up主'; var ul = document.getElementById('my-fubd--msgbox-targetcontainer'); ul.innerHTML = ''; for (var i = 0; i < len; i++) { ul.innerHTML += '
  • ' + checkedList[i] + '
  • '; } var base = document.getElementById('my-fubd--container'); base.className = 'modal-container edit-video-modal fade-enter fade-enter-active'; base.style = ''; setTimeout(function() { base.className = 'modal-container edit-video-modal fade-enter-active'; }, 10); } //退出消息框 function exitMessageBox() { var base = document.getElementById('my-fubd--container'); base.className = 'modal-container edit-video-modal fade-leave-active'; setTimeout(function() { base.className = 'modal-container edit-video-modal fade-leave fade-leave-active'; }, 10); setTimeout(function() { document.getElementById('my-fubd--container').style = 'display: none;'; base.className = 'modal-container edit-video-modal'; }, 300); } //主函数 async function mainFunc() { var csrf = getCookie('bili_jct'); var upElementsOnCurrentPage = document.getElementsByClassName('list-item clearfix list-item-select'); ///////////////////////////////////////WIP var upsOnCurrentPage = []; var upUidsOnCurrentPage = []; var i, len; for (i = 0, len = upElementsOnCurrentPage.length; i < len; i++) { var tmp = upElementsOnCurrentPage[i]; if (tmp.querySelector('.icon-follow-selected') != null) { upsOnCurrentPage.push(tmp); upUidsOnCurrentPage.push(digitRegex.exec(tmp.querySelector('.title').href)[0]); } } for (i = 0, len = checkedList.length; i < len; i++) { await mscststs.sleep(200); //延时 var uid = checkedList[i]; var index = upUidsOnCurrentPage.indexOf(uid); if (index != -1) { var t = upsOnCurrentPage[index].querySelector('.fans-action-btn .be-dropdown-item:nth-child(2)'); if (t) t.click(); } else { xhrPost(uid, csrf); } } exitMessageBox(); checkedList = []; updateIcon(); }